fix(mysql): pull INVISIBLE/GIPK columns during snapshot#4553
Conversation
The SELECT * snapshot fast path relied on wildcard expansion, which omits INVISIBLE columns (and the generated invisible primary key, my_row_id). The destination table and CDC both include those columns, so snapshot rows kept destination defaults forever while CDC populated real values — silent divergence. For GIPK the invisible my_row_id is the only PK, so snapshot rows arrived with no key, breaking dedup/ordering. Always build an explicit column list from the fetched table schema so invisible columns are named explicitly (bypassing wildcard invisibility). Add INVISIBLE and GIPK e2e tests comparing snapshot and CDC. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
There was a problem hiding this comment.
Pull request overview
This PR fixes MySQL/MariaDB QRep snapshot consistency by ensuring snapshots explicitly select all columns from the fetched schema (including INVISIBLE and generated invisible primary key columns), aligning snapshot output with destination DDL and CDC/binlog row images.
Changes:
- Remove the
SELECT *fast-path by always building an explicit column list inbuildSelectedColumns. - Add MySQL/MariaDB minimum-version constants for invisible columns and MySQL GIPK.
- Add/extend unit + ClickHouse E2E tests to validate snapshot vs CDC consistency for INVISIBLE and GIPK scenarios.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
flow/pkg/mysql/validation.go |
Adds version gates for invisible columns and generated invisible primary keys used by tests. |
flow/connectors/mysql/qrep.go |
Removes the * selection fast-path so snapshots explicitly name columns (including INVISIBLE/GIPK). |
flow/connectors/mysql/qrep_test.go |
Updates and extends unit coverage to ensure selected columns are explicit (no *). |
flow/e2e/clickhouse_mysql_test.go |
Adds E2E consistency tests comparing snapshot vs CDC for INVISIBLE and GIPK columns. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| return selectedColumns | ||
| return strings.Join(columns, ", ") |
| require.NoError(s.t, s.source.Exec(s.t.Context(), `SET SESSION sql_generate_invisible_primary_key = ON`)) | ||
| require.NoError(s.t, s.source.Exec(s.t.Context(), fmt.Sprintf(` | ||
| CREATE TABLE IF NOT EXISTS %s ( | ||
| name VARCHAR(50) NOT NULL | ||
| ) | ||
| `, srcFullName))) | ||
| require.NoError(s.t, s.source.Exec(s.t.Context(), `SET SESSION sql_generate_invisible_primary_key = OFF`)) |
❌ Test FailureAnalysis: The new Test_MySQL_GIPK_Consistency test — which validates the exact GIPK-snapshot feature this PR adds — hangs with the mirror "stuck in snapshot" and times out in STATUS_SETUP consistently across both MySQL 6.0 and 8.0 matrix configs, indicating a real bug in the PR's snapshot logic rather than a flaky failure. |
ilidemi
left a comment
There was a problem hiding this comment.
The task will need e2e checking on how this shows up in ClickPipes UI and whether it passes validations
|
Oh CI doesn't pass, something's up |
❌ 2 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
🔄 Flaky Test DetectedAnalysis: Failures are timeout/race-based (GIPK test stuck in STATUS_SETUP past the 60s wait in both jobs, plus a SIGPIPE ordering race in TestRunPipeline_DstExitsWhileSrcWriting), all unrelated to the commit's Renovate-script change, indicating environmental flakiness rather than a real bug. ✅ Automatically retrying the workflow |
❌ Test FailureAnalysis: Both mysql-gtid jobs deterministically fail the PR's own feature test (Test_MySQL_GIPK_Consistency) with an identical STATUS_SETUP timeout, indicating the GIPK/INVISIBLE snapshot code this PR introduces hangs during setup — a real bug, not a flake. |
|
tested e2e with other clickpipes components, works fine |
Problem
MySQL/MariaDB QRep snapshot took a
SELECT *fast path inbuildSelectedColumns. Wildcard expansion omits INVISIBLE columns — including the generated invisible primary key (my_row_id) fromsql_generate_invisible_primary_key. But the destination table (created frominformation_schema.columns) and CDC (binlog row images) both include those columns.Result: snapshot rows keep destination defaults forever while CDC populates real values — silent divergence. Worst case is GIPK, where the invisible
my_row_idis the table's only PK, so snapshot rows arrive with no key, breaking dedup/ordering.Fix
Always build an explicit column list from the fetched table schema (drop the
SELECT *fast path). The schema already contains invisible/GIPK columns, and naming them explicitly bypasses wildcard invisibility, so the snapshot pulls them — matching CDC and the destination DDL.Tests
buildSelectedColumnsnever returns*; invisible/GIPK columns are listed explicitly.clickhouse_mysql_test.go):Test_MySQL_Invisible_Column_ConsistencyandTest_MySQL_GIPK_Consistencycompare snapshot vs CDC values (version-gated; GIPK is MySQL-only).🤖 Generated with Claude Code